﻿using System;
using System.Collections.Generic;
using System.Text;

namespace NielsRask.K242.Core.AI
{
	public abstract class General
	{
		public Emperor Emperor { get; protected set; }
		protected List<Fleet> fleets;

		public abstract void Update();
	}

	public class InitialGeneral : General
	{
		public InitialGeneral(Emperor emperor)
		{
			this.Emperor = emperor;
			this.fleets = new List<Fleet>();
			foreach (Colony colony in Emperor.Colonies)
			{
				colony.ColonyLevelChanged += new Colony.ColonyLevelHandler(colony_ColonyLevelChanged);
			}
		}

		void colony_ColonyLevelChanged(Colony colony, ColonyLevel newLevel)
		{
			Emperor.General = new ExplorerGeneral(Emperor);
			colony.BuildShip();	// explorerGeneral er nu wired up med events til at reagere på ShipCompleted eventen
		}

		public override void Update()
		{
		}

	}

	public class ExplorerGeneral : General
	{
		public ExplorerGeneral(Emperor emperor)
		{
			this.Emperor = emperor;
			this.fleets = new List<Fleet>();
			foreach (Colony colony in Emperor.Colonies)
			{
				colony.ShipCompleted += new Colony.ShipCompletedHandler(colony_ShipCompleted);
			}
		}

		void colony_ShipCompleted(Colony colony, Ship ship)
		{
			Fleet reconFleet = new Fleet(this, colony.Asteroid.Position, ship);
			fleets.Add(reconFleet);
			lock ( Emperor.Sector.Fleets )
			{
				Emperor.Sector.Fleets.Add( reconFleet );
			}
			colony.HomeFleet.Remove(ship);

			for (int j = 0; j < 5; j++)
				reconFleet.Orders.Enqueue(new MoveOrder(Emperor.Sector.GetRandomPoint()));
			reconFleet.Orders.Enqueue(new MoveOrder(colony.Asteroid.Position));

			reconFleet.AsteroidDiscovered += new Fleet.AsteroidDiscoveredHandler(reconFleet_AsteroidDiscovered);

		}

		void reconFleet_AsteroidDiscovered(Asteroid asteroid)
		{
			if (asteroid.Colony != null)
			{
				if (asteroid.Colony.Emperor != Emperor)
				{
					asteroid.EmperorKnowledge[Emperor] = EmperorInfo.Hostile;
					Console.WriteLine(asteroid.Name + ": A hostile colony was discovered!!!");
					// sæt wargeneral
				}
				else
				{
					asteroid.EmperorKnowledge[Emperor] = EmperorInfo.Own;
					//Console.WriteLine("Making flyby of friendly colony");
				}
			}
			else
			{
				if (asteroid.EmperorKnowledge.ContainsKey(Emperor) == false)
				{
					Console.WriteLine(asteroid.Name + ": An uninhabited asteroid was discovered!!!");
					asteroid.EmperorKnowledge[Emperor] = EmperorInfo.Uninhabited;
					// set expandGeneral
					Emperor.General = new ExpandGeneral( Emperor );
				}
			}
		}

		public override void Update()
		{
		}

	}

	public class ExpandGeneral : General
	{
		public ExpandGeneral( Emperor emperor )
		{
			this.Emperor = emperor;
			this.fleets = new List<Fleet>();
			foreach ( Colony colony in Emperor.Colonies )
			{
				colony.ShipCompleted += new Colony.ShipCompletedHandler( colony_ShipCompleted );
				if ( colony.Level == ColonyLevel.NavalBase )
					colony.BuildShip();
			}
		}

		void colony_ShipCompleted( Colony colony, Ship ship )
		{
			if ( ship is ColonyShip )
			{
				Fleet colonyFleet = new Fleet( this, colony.Asteroid.Position, ship );
				fleets.Add( colonyFleet );
				lock ( Emperor.Sector.Fleets )
				{
					Emperor.Sector.Fleets.Add( colonyFleet );
				}
				colony.HomeFleet.Remove( ship );

				foreach ( Asteroid asteroid in Emperor.Sector.Asteroids )
				{
					if ( asteroid.EmperorKnowledge[ Emperor ] == EmperorInfo.Uninhabited )
					{
						colonyFleet.Orders.Enqueue( new MoveOrder( asteroid.Position) );
						colonyFleet.Orders.Enqueue( new ColonizeOrder( asteroid ) );
						break;
					}
				}
				//colonyFleet.Orders.Enqueue( new MoveOrder(

			}
		}

		void reconFleet_AsteroidDiscovered( Asteroid asteroid )
		{
			if ( asteroid.Colony != null )
			{
				if ( asteroid.Colony.Emperor != Emperor )
				{
					asteroid.EmperorKnowledge[ Emperor ] = EmperorInfo.Hostile;
					Console.WriteLine( asteroid.Name + ": A hostile colony was discovered!!!" );
					// sæt wargeneral
				}
				else
				{
					asteroid.EmperorKnowledge[ Emperor ] = EmperorInfo.Own;
					//Console.WriteLine("Making flyby of friendly colony");
				}
			}
			else
			{
				if ( asteroid.EmperorKnowledge.ContainsKey( Emperor ) == false )
				{
					Console.WriteLine( asteroid.Name + ": An uninhabited asteroid was discovered!!!" );
					asteroid.EmperorKnowledge[ Emperor ] = EmperorInfo.Uninhabited;
					// set expandGeneral
				}
			}
		}

		public override void Update()
		{
		}

	}


	public enum GeneralState
	{
		None, Explore, Readyness, War
	}

	/* tilstande + overgange
	 * Initiel:
	 * shipyard bygget -> Explore
	 * 
	 * Explore:
	 * Byg scout og send afsted
	 * Ledig asteriode fundet -> Expand
	 * Fjendtlig koloni fundet -> Arming
	 * 
	 * Expand:
	 * Byg colonyship, send afsted mod asteroide
	 * Fjendtlig koloni fundet -> Arming
	 * 
	 * Arming:
	 * opbyg flåde(r), angrib fjende
	 * 
	 * 
	 * arming er subset af expand, som er subset af explore, til dels ..
	 */
}
